package cn.fintecher.pangolin.service.dataimp.task;

import cn.fintecher.pangolin.common.enums.ImportDataExcelStatus;
import cn.fintecher.pangolin.common.enums.MessageType;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.BaseCase;
import cn.fintecher.pangolin.entity.elastic.CaseTransferLog;
import cn.fintecher.pangolin.entity.elastic.DistributeImportRecord;
import cn.fintecher.pangolin.entity.elastic.DistributeModel;
import cn.fintecher.pangolin.entity.mysql.CaseInfo;
import cn.fintecher.pangolin.service.dataimp.elastic.BaseCaseElastic;
import cn.fintecher.pangolin.service.dataimp.elastic.CaseTransferLogElastic;
import cn.fintecher.pangolin.service.dataimp.elastic.DistributeImportRecordElastic;
import cn.fintecher.pangolin.service.dataimp.elastic.DistributeModelElastic;
import cn.fintecher.pangolin.service.dataimp.model.DistributeConfirmModel;
import cn.fintecher.pangolin.service.dataimp.repository.CaseInfoRepository;
import cn.fintecher.pangolin.service.dataimp.service.BaseService;
import cn.fintecher.pangolin.common.utils.RepositoryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 14:20 2019/10/18
 */

@Service("confirmDistributeTask")
public class ConfirmDistributeTask {
    private static final Logger log = LoggerFactory.getLogger(ConfirmDistributeTask.class);

    @Autowired
    private DistributeImportRecordElastic distributeImportRecordElastic;

    @Autowired
    private CaseInfoRepository caseInfoRepository;

    @Autowired
    private BaseCaseElastic baseCaseElastic;

    @Autowired
    private CaseTransferLogElastic caseTransferLogElastic;

    @Autowired
    private BaseService baseService;

    @Autowired
    private ConfirmDistributeFuture confirmDistributeFuture;

    @Autowired
    private DistributeModelElastic distributeModelElastic;

    /**
     * 异步确认
     */
    @Async
    @Transactional
    public void confirmImportDistribute(List<DistributeModel> models, UserModel userModel, DistributeImportRecord record) {
        //创建任务集合
        List<CompletableFuture<DistributeConfirmModel>> list = new ArrayList<>();
        //分页处理信息
        int pageSize = 2000;
        int pageNumber = (int) Math.ceil((double) models.size() / (double) pageSize);
        for (int i = 0; i < pageNumber; i++) {
            List<DistributeModel> distributeModels = models.stream().skip(i * pageSize).limit(pageSize).collect(Collectors.toList());
            CompletableFuture<DistributeConfirmModel> task = confirmDistributeFuture.processDistribute(distributeModels, userModel);
            list.add(task);
        }
        List<CaseInfo> caseInfos = new ArrayList<>();
        List<BaseCase> baseCases = new ArrayList<>();
        List<CaseTransferLog> caseTransferLogs = new ArrayList<>();
        List<DistributeModel> distributeModels = new ArrayList<>();
        List<String> errors = new ArrayList<>();
        List<DistributeConfirmModel> distributeConfirmModels = new ArrayList<>();
        try {
            for (CompletableFuture<DistributeConfirmModel> future : list) {
                distributeConfirmModels.add(future.get());
            }
            if (!distributeConfirmModels.isEmpty()) {
                distributeConfirmModels.forEach(e -> {
                    caseInfos.addAll(e.getCaseInfos());
                    baseCases.addAll(e.getBaseCases());
                    caseTransferLogs.addAll(e.getCaseTransferLogs());
                    distributeModels.addAll(e.getDistributeModels());
                    errors.addAll(e.getErrors());
                });
            }
            if (!errors.isEmpty()) {
                record.setStatus(ImportDataExcelStatus.UN_CONFIRMED);
                String fileId = baseService.generateTxt(errors, ZWDateUtil.fomratterDate(new Date(), "yyyyMMdd"));
                record.setFileId(fileId);
            } else {
                record.setStatus(ImportDataExcelStatus.CONFIRMED);
                record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
                RepositoryUtil.saveData(baseCaseElastic, baseCases);
                RepositoryUtil.saveData(caseInfoRepository, caseInfos);
                RepositoryUtil.saveData(caseTransferLogElastic, caseTransferLogs);
                RepositoryUtil.saveData(distributeModelElastic, distributeModels);
            }
            distributeImportRecordElastic.save(record);
        } catch (InterruptedException | ExecutionException e) {
            log.error(e.getMessage(), e);
            record.setStatus(ImportDataExcelStatus.UN_CONFIRMED);
            record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
            distributeImportRecordElastic.save(record);
        } finally {
            baseService.sendMsg(MessageType.DISTRIBUTE_CONFIRM, userModel);
        }
    }
}
